# -*- coding: utf-8 -*-
import time

from machine import Pin
from machine import PWM
from neopixel import NeoPixel
from machine import Timer

import netServer

class Wheel(object):
    pinN = None
    pinP = None
    def __init__(self, pina, pinb, speedoff = 0):
        self.pinN = PWM(Pin(pina, Pin.OUT), freq=1000)
        self.pinP = PWM(Pin(pinb, Pin.OUT), freq=1000)
        self.speedOffset = speedoff

    def go(self, speed = 512):
        self.pinN.duty(0)
        self.pinP.duty(speed+self.speedOffset)
    def back(self, speed = 512):
        self.pinN.duty(speed+self.speedOffset)
        self.pinP.duty(0)
    def stop(self):
        self.pinN.duty(1023)
        self.pinP.duty(1023)
    def pause(self):
        self.pinP.duty(0)
        self.pinN.duty(0)
        
class Car(object):
    STOP = 0
    LEFT = 1
    RIGHT = 2
    GO = 3
    BACK = 4
    FULL_BRIGHT=30
    
    STATE_WIFI_CONNECTING = 1
    STATE_WIFI_CONNECTED = 2
    STATE_SOCKET_WAIT_CONNECT = 3
    STATE_SOCKET_CONNECTED = 4
    STATE_IDLE = 5
    STATE_EXE_CMD = 6
    def __init__(self):
        self.wFrontLeft = Wheel(4, 5)
        self.wFrontRight = Wheel(6, 7, 40)
        self.wBackLeft = Wheel(15,16)
        self.wBackRight = Wheel(17,18, 40)
        self.npLight = NeoPixel(Pin(48, Pin.OUT), 8)
        self.dir = self.GO
        self.speed = 512
    def go(self, speed = 512):
        self.wBackLeft.go(speed)
        self.wBackRight.go(speed)
        self.wFrontLeft.go(speed)
        self.wFrontRight.go(speed)
        self.dir = self.GO
        self.speed = speed
    def stop(self):
        self.wBackLeft.stop()
        self.wBackRight.stop()
        self.wFrontLeft.stop()
        self.wFrontRight.stop()
        self.dir = self.STOP
        
    def back(self, speed = 512):
        self.wBackLeft.back(speed)
        self.wBackRight.back(speed)
        self.wFrontLeft.back(speed)
        self.wFrontRight.back(speed)
        self.dir = self.BACK
        self.speed = speed
        
    def left(self, mode = 0):
        if mode == 0:
            self.wFrontLeft.pause()
            self.wFrontRight.go(self.speed)
            self.wBackLeft.pause()
            self.wBackRight.go(self.speed)
        else:
            self.wFrontLeft.back(self.speed)
            self.wFrontRight.go(self.speed)
            self.wBackLeft.back(self.speed)
            self.wBackRight.go(self.speed)
        self.dir = self.LEFT
    def pause(self):
        self.wFrontLeft.pause()
        self.wFrontRight.pause()
        self.wBackLeft.pause()
        self.wBackRight.pause()
        self.dir = self.STOP

    def right(self, mode = 0):
        if mode == 0:
            self.wFrontLeft.go()
            self.wFrontRight.pause()
            self.wBackLeft.go()
            self.wBackRight.pause()
        else:
            self.wFrontLeft.go()
            self.wFrontRight.back()
            self.wBackLeft.go()
            self.wBackRight.back()
            
        self.dir = self.RIGHT
    
    def setspeed(self, speed):
        self.speed = speed
        if self.dir == self.GO:
            self.go(speed)
        elif self.dir == self.BACK:
            self.back(speed)
    
    def ligtht(self, color):
        self.npLight[0] = color
        self.npLight.write()

    def _flashCallback(self, timer):
        if (0,0,0) == self.npLight[0]:
            self.ligtht(self._flashColor)
        else:
            self.ligtht((0,0,0))
            
    def flashOn(self, color: tuple, freq:int):
        self._flashColor = color
        self.ligtht(color)
        self.flashTimer = Timer(0)
        self.flashTimer.init(mode=Timer.PERIODIC, period=freq, callback=self._flashCallback)

    def flashOff(self, color: tuple):
        self.ligtht(color)
        self.flashTimer.deinit()

    
    def state(self, state):
        if state == self.STATE_WIFI_CONNECTING:
            self.flashOn((int(self.FULL_BRIGHT/10),0,0), 100)
        elif state == self.STATE_WIFI_CONNECTED:
            self.flashOff((int(self.FULL_BRIGHT/10),0,0))
        elif state == self.STATE_SOCKET_WAIT_CONNECT:
            self.flashOn((0,int(self.FULL_BRIGHT/10),0), 100)
        elif state == self.STATE_SOCKET_CONNECTED:
            self.flashOff((0,int(self.FULL_BRIGHT/10),0))
        elif state == self.STATE_IDLE:
            self.ligtht((0,int(self.FULL_BRIGHT/20),0))
        elif state == self.STATE_EXE_CMD:
            self.ligtht((0,0,int(self.FULL_BRIGHT)))
        else:
            pass





car = Car()
def start_bak():
    time.sleep(2)
    while True:
        time.sleep(2)
        print("go")
        car.go()
        time.sleep(1)
        car.stop()
        time.sleep(1)
        car.setspeed(684)
        car.left(1)
        time.sleep(0.5)
        car.setspeed(512)
        car.go()
        time.sleep(1)
        car.stop()
def start():
    ns = netServer.NetServer()
    car.state(Car.STATE_WIFI_CONNECTING)

    while True:
        if ns.connect('TP-LINK_257ECC','PLL3V70800', 10):
            break
    print('connect wifi ok')
    car.state(Car.STATE_WIFI_CONNECTED)


    ns.boardcast(90, 5)
    ns.createServer(80)
    car.state(Car.STATE_SOCKET_WAIT_CONNECT)
    c = ns.waitConnect(0)
    car.state(Car.STATE_SOCKET_CONNECTED)

    while True:
        cmd = ns.readCmd(c, 0.2)
        if cmd == None:
            car.pause()
            car.state(Car.STATE_IDLE)
            continue
        car.state(Car.STATE_EXE_CMD)
        if cmd == b'W':
            if car.dir != Car.GO:
                car.go()
        elif cmd == b'A':
            if car.dir != Car.LEFT:
                car.left()
        elif cmd == b'D':
            if car.dir != Car.RIGHT:
                car.right()
        elif cmd == b'S':
            if car.dir != Car.BACK:
                car.back()
        else:
            pass


if __name__ == '__main__':
    start()

